package com.easipass.unifiedconfig.unic;

import java.util.Collection;
import java.util.Collections;
import java.util.Hashtable;
import java.util.LinkedHashSet;
import java.util.Map;

import com.easipass.unifiedconfig.NotFoundException;
import com.easipass.unifiedconfig.Parameter;
import com.easipass.unifiedconfig.ParametersTraverser;
import com.easipass.unifiedconfig.UCI;
import com.easipass.unifiedconfig.NotFoundException.Part;
import com.easipass.unifiedconfig.Parameter.AccessLevel;
import com.easipass.unifiedconfig.core.Authentication;

/**
 * 
 * @version $Id$
 * @author itea
 * @date 2010-1-19
 */
public class ModuleRepo {
	
	protected final String module;
	
	protected final AccessLevel defaultAccessLevel;
	
	protected Map<String, Parameter> parameterIdx = new Hashtable<String, Parameter>();
	
	public ModuleRepo(String module) {
		super();
		this.module = module;
		this.defaultAccessLevel = AccessLevel.PUBLIC;
	}
	
	public ModuleRepo(String module, AccessLevel defualtAccessLevel) {
		super();
		this.module = module;
		this.defaultAccessLevel = defualtAccessLevel;
	}

	public Parameter getParameter(UCI uci) throws NotFoundException{
		if(!uci.matchesModule(module))
			throw new NotFoundException(Part.MODULE, uci);
		
		Parameter p = parameterIdx.get(uci.getParameterName());
		if(p == null)
			throw new NotFoundException(Part.PARAMETER, uci);
		return p;
	}
	
	public void setParameter(Parameter p) throws NotFoundException {
		if(p.getName() == null)
			throw new NotFoundException(Part.PARAMETER, p.getUci());
		parameterIdx.put(p.getName(), p);
	}

	public void removeParameter(UCI u) throws NotFoundException {
		if(u.getParameterName() == null)
			throw new NotFoundException(Part.PARAMETER, u);
		parameterIdx.remove(u.getParameterName());
	}
	
	public boolean containsParameter(UCI u) {
		if(u.getParameterName() == null)
			return false;
		return parameterIdx.containsKey(u.getParameterName());
	}
	
	public Collection<UCI> listParameters(UCI range) {
		if(!range.matchesModule(module))
			return Collections.emptyList();
		
		LinkedHashSet<UCI> ucis = new LinkedHashSet<UCI>();
		for(Parameter p : parameterIdx.values())
			if(range.obtains(p.getUci()))
				ucis.add(p.getUci());
		return ucis;
	}
	public void traverseParameters(Authentication a, UCI range, ParametersTraverser traverser) {
		for(Parameter p : parameterIdx.values()) {
			if(!range.obtains(p.getUci())) continue;
		
			if(AccessLevel.PRIVATE == p.getAccessLevel()) {
				if(a.authorized(p.getUci()))
					traverser.accessParameter(p.clone());
			} else
				traverser.accessParameter(p.clone());
		}
	}
	public String getModule() {
		return module;
	}
}
